package com.gouda.core.dao;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.gouda.core.entity.UseCityEntity;
import com.gouda.core.enums.GeneralStateEnum;
import com.gouda.core.utils.CacheKey;
import com.hephaestus.cache.CacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.amethyst.atlas.basic.entity.MagicDBEntity;
import org.amethyst.atlas.db.MagicDao;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by souu on 15/12/5.
 */
@Slf4j
@Repository
public class UseCityDao extends MagicDao {

    private static final String BASE_SQL = "select id,city_name,isall,state,create_time from use_city";

    private static final String BASE_SQL_ID = "select id from use_city";

    public UseCityEntity getUseCityByCityName(String cityName) {
        if (Strings.isNullOrEmpty(cityName)) {
            return null;
        }
        Long id = (Long) CacheUtil.getInstance().get(CacheKey.getUseCityByCityName(cityName));
        if (id == null) {
            StringBuilder sql = new StringBuilder("");
            sql.append(BASE_SQL_ID);
            sql.append(" where city_name like :cityName");
            sql.append(" and state = :state");
            sql.append(" order by id desc limit 1");
            Map<String, Object> param = Maps.newHashMap();
            param.put("cityName", "%" + cityName + "%");
            param.put("state", GeneralStateEnum.YES.getCode());
            List<Long> ids = this.listColumns(UseCityEntity.class, sql.toString(), param, Long.class);
            if (ids == null || ids.isEmpty()) {
                return null;
            }
            id = ids.get(0);
            try {
                CacheUtil.getInstance().add(CacheKey.getUseCityByCityName(cityName), id, DateUtils.addHours(new Date(), 1));
            } catch (InterruptedException e) {
                log.error("getUseCityByCityName cache error:{}", e.getMessage());
            }
        }

        return this.unique(UseCityEntity.class, id);
    }

    public List<UseCityEntity> getAllUseCity() {
        List<Long> ids = (List<Long>) CacheUtil.getInstance().get(CacheKey.getAllUseCity());
        if (ids == null || ids.isEmpty()) {
            StringBuilder sql = new StringBuilder("");
            sql.append(BASE_SQL_ID);
            sql.append(" where state = :state");
            sql.append(" order by create_time asc");
            Map<String, Object> param = Maps.newHashMap();
            param.put("state", GeneralStateEnum.YES.getCode());
            ids = super.listColumns(UseCityEntity.class, sql.toString(), param, Long.class);
            if (ids == null || ids.isEmpty()) {
                return null;
            }
            try {
                CacheUtil.getInstance().add(CacheKey.getAllUseCity(), ids);
            } catch (InterruptedException e) {
                log.error("getAllUseCity cache error:{}", e.getMessage());
            }
        }

        List<UseCityEntity> list = Lists.newArrayList();
        for (Long id : ids) {
            UseCityEntity entity = this.unique(UseCityEntity.class, id.longValue());
            if (entity != null) {
                list.add(entity);
            }
        }
        return list;
    }


    public boolean insert(final UseCityEntity entity) {
        boolean bool = super.insert(entity);
        if (bool) {
            try {
                CacheUtil.getInstance().delete(CacheKey.getAllUseCity());
            } catch (InterruptedException e) {
                log.error("useCityInsert cache error:{}", e.getMessage());
            }
        }
        return bool;
    }


    public boolean update(final UseCityEntity entity) {
        boolean bool = super.update(entity);
        if (bool) {
            try {
                CacheUtil.getInstance().delete(CacheKey.getAllUseCity());
            } catch (InterruptedException e) {
                log.error("useCityUpdate cache error:{}", e.getMessage());
            }
        }
        return bool;
    }
}
